<?php
namespace app\common\repositories\merchant;

use app\common\model\merchant\MerchantModel;
use app\common\model\merchant\MerchantApiKeyModel;
use app\common\model\merchant\MerchantStatsModel;
use support\Db;
use support\Log;
use support\Redis;
use support\Request;

/**
 * 商户管理仓库
 * 处理商户注册、认证、API密钥管理等核心业务逻辑
 */
class MerchantRepository
{
    protected $merchantModel;
    protected $apiKeyModel;
    protected $statsModel;

    public function __construct()
    {
        $this->merchantModel = new MerchantModel();
        $this->apiKeyModel = new MerchantApiKeyModel();
        $this->statsModel = new MerchantStatsModel();
    }

    /**
     * 商户注册
     */
    public function registerMerchant($data)
    {
        $validateResult = $this->validateRegistrationData($data);
        if (!$validateResult['valid']) {
            return ['code' => 400, 'msg' => $validateResult['message']];
        }

        try {
            Db::beginTransaction();

            // 创建商户
            $merchantData = [
                'company_name' => $data['company_name'],
                'contact_name' => $data['contact_name'],
                'email' => $data['email'],
                'phone' => $data['phone'] ?? '',
                'password' => password_hash($data['password'], PASSWORD_DEFAULT),
                'status' => 'pending',
                'verification_token' => $this->generateVerificationToken(),
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];

            $merchantId = $this->merchantModel->insertGetId($merchantData);

            // 创建默认API密钥
            $apiKey = $this->createApiKey($merchantId, 'Default Key');

            Db::commit();

            // 发送验证邮件
            $this->sendVerificationEmail($merchantData['email'], $merchantData['verification_token']);

            return [
                'code' => 200,
                'msg' => 'Registration successful. Please check your email for verification.',
                'data' => [
                    'merchant_id' => $merchantId,
                    'api_key' => $apiKey['api_key'],
                    'api_secret' => $apiKey['api_secret']
                ]
            ];

        } catch (\Exception $e) {
            Db::rollBack();
            Log::error('Merchant registration failed: ' . $e->getMessage());
            return ['code' => 500, 'msg' => 'Registration failed. Please try again.'];
        }
    }

    /**
     * 商户登录
     */
    public function loginMerchant($email, $password)
    {
        $merchant = $this->merchantModel->where('email', $email)->find();
        
        if (!$merchant) {
            return ['code' => 401, 'msg' => 'Invalid credentials'];
        }

        if (!password_verify($password, $merchant['password'])) {
            return ['code' => 401, 'msg' => 'Invalid credentials'];
        }

        if ($merchant['status'] !== 'active') {
            return ['code' => 403, 'msg' => 'Account not activated. Please verify your email.'];
        }

        // 生成登录token
        $token = $this->generateLoginToken($merchant['id']);
        
        // 更新最后登录时间
        $this->merchantModel->where('id', $merchant['id'])->update([
            'last_login_at' => date('Y-m-d H:i:s')
        ]);

        return [
            'code' => 200,
            'msg' => 'Login successful',
            'data' => [
                'merchant' => [
                    'id' => $merchant['id'],
                    'company_name' => $merchant['company_name'],
                    'email' => $merchant['email'],
                    'status' => $merchant['status']
                ],
                'token' => $token,
                'expires_at' => date('Y-m-d H:i:s', strtotime('+24 hours'))
            ]
        ];
    }

    /**
     * 验证邮箱
     */
    public function verifyEmail($token)
    {
        $merchant = $this->merchantModel->where('verification_token', $token)->find();
        
        if (!$merchant) {
            return ['code' => 400, 'msg' => 'Invalid verification token'];
        }

        if ($merchant['verified_at'] !== null) {
            return ['code' => 400, 'msg' => 'Email already verified'];
        }

        $this->merchantModel->where('id', $merchant['id'])->update([
            'status' => 'active',
            'verified_at' => date('Y-m-d H:i:s'),
            'verification_token' => null,
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        return ['code' => 200, 'msg' => 'Email verified successfully'];
    }

    /**
     * 获取商户详情
     */
    public function getMerchantDetail($merchantId)
    {
        $merchant = $this->merchantModel->find($merchantId);
        
        if (!$merchant) {
            return ['code' => 404, 'msg' => 'Merchant not found'];
        }

        // 获取API密钥列表
        $apiKeys = $this->apiKeyModel->where('merchant_id', $merchantId)->select();

        // 获取今日统计数据
        $todayStats = $this->getTodayStats($merchantId);

        return [
            'code' => 200,
            'data' => [
                'merchant' => [
                    'id' => $merchant['id'],
                    'company_name' => $merchant['company_name'],
                    'contact_name' => $merchant['contact_name'],
                    'email' => $merchant['email'],
                    'phone' => $merchant['phone'],
                    'status' => $merchant['status'],
                    'verified_at' => $merchant['verified_at'],
                    'created_at' => $merchant['created_at'],
                    'last_login_at' => $merchant['last_login_at']
                ],
                'api_keys' => $apiKeys,
                'stats' => $todayStats,
                'quota' => $this->getMerchantQuota($merchantId)
            ]
        ];
    }

    /**
     * 创建API密钥
     */
    public function createApiKey($merchantId, $name = '', $permissions = ['read', 'write'])
    {
        $apiKey = $this->generateApiKey();
        $apiSecret = $this->generateApiSecret();

        $keyData = [
            'merchant_id' => $merchantId,
            'name' => $name ?: 'API Key ' . date('Y-m-d H:i:s'),
            'api_key' => $apiKey,
            'api_secret' => password_hash($apiSecret, PASSWORD_DEFAULT),
            'permissions' => json_encode($permissions),
            'daily_requests_limit' => 10000,
            'daily_requests_used' => 0,
            'total_requests_used' => 0,
            'status' => 'active',
            'expires_at' => date('Y-m-d H:i:s', strtotime('+1 year')),
            'last_used_at' => null,
            'created_at' => date('Y-m-d H:i:s')
        ];

        $keyId = $this->apiKeyModel->insertGetId($keyData);

        return [
            'id' => $keyId,
            'api_key' => $apiKey,
            'api_secret' => $apiSecret,
            'permissions' => $permissions,
            'expires_at' => $keyData['expires_at']
        ];
    }

    /**
     * 验证API密钥
     */
    public function validateApiKey($apiKey, $apiSecret = null)
    {
        $keyRecord = $this->apiKeyModel->where('api_key', $apiKey)->find();
        
        if (!$keyRecord) {
            return ['valid' => false, 'reason' => 'API key not found'];
        }

        if ($keyRecord['status'] !== 'active') {
            return ['valid' => false, 'reason' => 'API key is inactive'];
        }

        if (strtotime($keyRecord['expires_at']) < time()) {
            return ['valid' => false, 'reason' => 'API key has expired'];
        }

        // 如果提供了secret，验证它
        if ($apiSecret && !password_verify($apiSecret, $keyRecord['api_secret'])) {
            return ['valid' => false, 'reason' => 'Invalid API secret'];
        }

        // 检查商户状态
        $merchant = $this->merchantModel->find($keyRecord['merchant_id']);
        if (!$merchant || $merchant['status'] !== 'active') {
            return ['valid' => false, 'reason' => 'Merchant account is inactive'];
        }

        return [
            'valid' => true,
            'merchant_id' => $keyRecord['merchant_id'],
            'permissions' => json_decode($keyRecord['permissions'], true),
            'quota' => [
                'daily_limit' => $keyRecord['daily_requests_limit'],
                'daily_used' => $keyRecord['daily_requests_used'],
                'remaining' => $keyRecord['daily_requests_limit'] - $keyRecord['daily_requests_used']
            ]
        ];
    }

    /**
     * 获取商户统计数据
     */
    public function getMerchantStats($merchantId, $startDate = null, $endDate = null)
    {
        $startDate = $startDate ?: date('Y-m-d', strtotime('-30 days'));
        $endDate = $endDate ?: date('Y-m-d');

        // 获取应用列表
        $apps = $this->merchantModel->find($merchantId)->getApps();
        $appIds = array_column($apps->toArray(), 'id');

        if (empty($appIds)) {
            return ['code' => 200, 'data' => $this->getEmptyStats()];
        }

        // 获取归因统计数据
        $attributionStats = $this->getAttributionStats($appIds, $startDate, $endDate);
        
        // 获取事件统计数据
        $eventStats = $this->getEventStats($appIds, $startDate, $endDate);

        // 获取渠道分析数据
        $channelStats = $this->getChannelStats($appIds, $startDate, $endDate);

        return [
            'code' => 200,
            'data' => [
                'summary' => $attributionStats['summary'],
                'trends' => $attributionStats['trends'],
                'events' => $eventStats,
                'channels' => $channelStats,
                'top_apps' => $attributionStats['top_apps']
            ]
        ];
    }

    /**
     * 获取API密钥列表
     */
    public function getApiKeys($merchantId)
    {
        $apiKeys = $this->apiKeyModel
            ->where('merchant_id', $merchantId)
            ->where('status', '!=', 'deleted')
            ->orderBy('created_at', 'desc')
            ->select();

        $result = [];
        foreach ($apiKeys as $key) {
            $result[] = [
                'id' => $key['id'],
                'name' => $key['name'],
                'api_key' => $key['api_key'],
                'permissions' => json_decode($key['permissions'], true),
                'daily_requests_limit' => $key['daily_requests_limit'],
                'daily_requests_used' => $key['daily_requests_used'],
                'total_requests_used' => $key['total_requests_used'],
                'status' => $key['status'],
                'expires_at' => $key['expires_at'],
                'last_used_at' => $key['last_used_at'],
                'created_at' => $key['created_at']
            ];
        }

        return $result;
    }

    /**
     * 删除API密钥
     */
    public function deleteApiKey($merchantId, $keyId)
    {
        $key = $this->apiKeyModel->where('id', $keyId)->where('merchant_id', $merchantId)->find();
        
        if (!$key) {
            return ['code' => 404, 'msg' => 'API key not found'];
        }

        $this->apiKeyModel->where('id', $keyId)->update(['status' => 'deleted']);
        
        return ['code' => 200, 'msg' => 'API key deleted successfully'];
    }

    /**
     * 重置API密钥
     */
    public function resetApiKey($merchantId, $keyId)
    {
        $key = $this->apiKeyModel->where('id', $keyId)->where('merchant_id', $merchantId)->find();
        
        if (!$key) {
            return ['code' => 404, 'msg' => 'API key not found'];
        }

        $newApiSecret = $this->generateApiSecret();
        $newApiKey = $this->generateApiKey();

        $this->apiKeyModel->where('id', $keyId)->update([
            'api_key' => $newApiKey,
            'api_secret' => password_hash($newApiSecret, PASSWORD_DEFAULT),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        return [
            'code' => 200,
            'msg' => 'API key reset successfully',
            'data' => [
                'api_key' => $newApiKey,
                'api_secret' => $newApiSecret
            ]
        ];
    }

    /**
     * 更新商户配额
     */
    public function updateQuota($merchantId, $quotaType, $newLimit)
    {
        $validQuotaTypes = ['daily_requests', 'apps_limit', 'storage_limit'];
        
        if (!in_array($quotaType, $validQuotaTypes)) {
            return ['code' => 400, 'msg' => 'Invalid quota type'];
        }

        $this->merchantModel->where('id', $merchantId)->update([
            $quotaType . '_limit' => $newLimit,
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        return ['code' => 200, 'msg' => 'Quota updated successfully'];
    }

    /**
     * 根据邮箱获取商户信息
     */
    public function getMerchantByEmail($email)
    {
        return $this->merchantModel->where('email', $email)->find();
    }

    /**
     * 商户登出
     */
    public function logout($merchantId)
    {
        // 这里可以添加清理token的逻辑
        return ['code' => 200, 'msg' => 'Logout successful'];
    }

    /**
     * 生成日期范围数组
     */
    private function generateDateRange($startDate, $endDate)
    {
        $start = new \DateTime($startDate);
        $end = new \DateTime($endDate);
        $end = $end->modify('+1 day'); // 包含结束日期

        $interval = new \DateInterval('P1D');
        $dateRange = new \DatePeriod($start, $interval, $end);

        $dates = [];
        foreach ($dateRange as $date) {
            $dates[] = $date->format('Y-m-d');
        }

        return $dates;
    }

    // 辅助方法
    private function validateRegistrationData($data)
    {
        $requiredFields = ['company_name', 'contact_name', 'email', 'password'];
        
        foreach ($requiredFields as $field) {
            if (empty($data[$field])) {
                return ['valid' => false, 'message' => "Field {$field} is required"];
            }
        }

        // 验证邮箱格式
        if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            return ['valid' => false, 'message' => 'Invalid email format'];
        }

        // 检查邮箱是否已存在
        $existing = $this->merchantModel->where('email', $data['email'])->find();
        if ($existing) {
            return ['valid' => false, 'message' => 'Email already registered'];
        }

        // 验证密码强度
        if (strlen($data['password']) < 8) {
            return ['valid' => false, 'message' => 'Password must be at least 8 characters'];
        }

        return ['valid' => true, 'message' => 'Validation passed'];
    }

    private function generateVerificationToken()
    {
        return bin2hex(random_bytes(32));
    }

    private function generateLoginToken($merchantId)
    {
        $payload = [
            'merchant_id' => $merchantId,
            'exp' => time() + 86400, // 24小时
            'iat' => time()
        ];
        
        return base64_encode(json_encode($payload));
    }

    private function generateApiKey()
    {
        return 'xapt_' . bin2hex(random_bytes(16));
    }

    private function generateApiSecret()
    {
        return bin2hex(random_bytes(32));
    }

    private function sendVerificationEmail($email, $token)
    {
        // 这里应该集成邮件服务
        // 暂时记录日志
        Log::info("Verification email sent to {$email} with token: {$token}");
    }

    private function getTodayStats($merchantId)
    {
        $today = date('Y-m-d');
        
        // 获取今日统计数据
        $stats = $this->statsModel->where([
            'merchant_id' => $merchantId,
            'stat_date' => $today
        ])->find();

        return $stats ? $stats->toArray() : [
            'clicks' => 0,
            'installs' => 0,
            'registers' => 0,
            'events' => 0
        ];
    }

    private function getMerchantQuota($merchantId)
    {
        $merchant = $this->merchantModel->find($merchantId);
        
        return [
            'daily_requests_limit' => $merchant['daily_requests_limit'] ?? 10000,
            'apps_limit' => $merchant['apps_limit'] ?? 10,
            'storage_limit' => $merchant['storage_limit'] ?? 1073741824, // 1GB
            'current_apps' => $merchant->getApps()->count(),
            'current_storage' => 0 // 需要计算实际存储使用
        ];
    }

    private function getEmptyStats()
    {
        return [
            'summary' => [
                'total_clicks' => 0,
                'total_installs' => 0,
                'total_registers' => 0,
                'conversion_rate' => 0
            ],
            'trends' => [],
            'events' => [],
            'channels' => [],
            'top_apps' => []
        ];
    }

    private function getAttributionStats($appIds, $startDate, $endDate)
    {
        // 获取归因追踪统计
        $clickStats = Db::table('gf_attribution_track')
            ->whereIn('appkey', $appIds)
            ->whereBetween('created_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('COUNT(*) as total_clicks, DATE(created_at) as click_date')
            ->groupBy('click_date')
            ->get();

        // 获取安装统计
        $installStats = Db::table('gf_attribution_install')
            ->whereIn('appkey', $appIds)
            ->whereBetween('install_time', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('COUNT(*) as total_installs, DATE(install_time) as install_date')
            ->groupBy('install_date')
            ->get();

        // 获取注册统计（假设注册事件类型为'register'）
        $registerStats = Db::table('gf_attribution_event')
            ->whereIn('appkey', $appIds)
            ->where('event_type', 'register')
            ->whereBetween('created_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('COUNT(*) as total_registers, DATE(created_at) as register_date')
            ->groupBy('register_date')
            ->get();

        // 计算汇总数据
        $totalClicks = $clickStats->sum('total_clicks');
        $totalInstalls = $installStats->sum('total_installs');
        $totalRegisters = $registerStats->sum('total_registers');
        $conversionRate = $totalClicks > 0 ? round(($totalInstalls / $totalClicks) * 100, 2) : 0;

        // 构建趋势数据
        $trends = [];
        $dateRange = $this->generateDateRange($startDate, $endDate);
        
        foreach ($dateRange as $date) {
            $clickData = $clickStats->firstWhere('click_date', $date);
            $installData = $installStats->firstWhere('install_date', $date);
            $registerData = $registerStats->firstWhere('register_date', $date);

            $trends[] = [
                'date' => $date,
                'clicks' => $clickData ? $clickData->total_clicks : 0,
                'installs' => $installData ? $installData->total_installs : 0,
                'registers' => $registerData ? $registerData->total_registers : 0,
                'conversion_rate' => ($clickData && $clickData->total_clicks > 0) 
                    ? round((($installData ? $installData->total_installs : 0) / $clickData->total_clicks) * 100, 2) 
                    : 0
            ];
        }

        // 获取应用排行数据
        $appStats = Db::table('gf_attribution_install')
            ->whereIn('appkey', $appIds)
            ->whereBetween('install_time', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('appkey, COUNT(*) as install_count')
            ->groupBy('appkey')
            ->orderByDesc('install_count')
            ->limit(10)
            ->get();

        $topApps = [];
        foreach ($appStats as $stat) {
            $app = Db::table('gf_apps')->where('appkey', $stat->appkey)->first();
            if ($app) {
                $topApps[] = [
                    'app_name' => $app->app_name,
                    'appkey' => $stat->appkey,
                    'installs' => $stat->install_count
                ];
            }
        }

        return [
            'summary' => [
                'total_clicks' => $totalClicks,
                'total_installs' => $totalInstalls,
                'total_registers' => $totalRegisters,
                'conversion_rate' => $conversionRate
            ],
            'trends' => $trends,
            'top_apps' => $topApps
        ];
    }

    private function getEventStats($appIds, $startDate, $endDate)
    {
        // 获取事件类型统计
        $eventStats = Db::table('gf_attribution_event')
            ->whereIn('appkey', $appIds)
            ->whereBetween('created_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('event_type, COUNT(*) as event_count, DATE(created_at) as event_date')
            ->groupBy(['event_type', 'event_date'])
            ->get();

        // 按事件类型分组
        $eventsByType = [];
        foreach ($eventStats as $stat) {
            if (!isset($eventsByType[$stat->event_type])) {
                $eventsByType[$stat->event_type] = [];
            }
            $eventsByType[$stat->event_type][] = [
                'date' => $stat->event_date,
                'count' => $stat->event_count
            ];
        }

        // 获取事件类型总计
        $eventTotals = Db::table('gf_attribution_event')
            ->whereIn('appkey', $appIds)
            ->whereBetween('created_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('event_type, COUNT(*) as total_count')
            ->groupBy('event_type')
            ->get();

        return [
            'by_type' => $eventsByType,
            'totals' => $eventTotals->pluck('total_count', 'event_type')->toArray()
        ];
    }

    private function getChannelStats($appIds, $startDate, $endDate)
    {
        // 获取渠道统计（从归因追踪表）
        $channelStats = Db::table('gf_attribution_track')
            ->whereIn('appkey', $appIds)
            ->whereNotNull('channel')
            ->whereBetween('created_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('channel, COUNT(*) as click_count, DATE(created_at) as stat_date')
            ->groupBy(['channel', 'stat_date'])
            ->get();

        // 获取渠道安装统计
        $channelInstallStats = Db::table('gf_attribution_install')
            ->whereIn('appkey', $appIds)
            ->whereNotNull('channel')
            ->whereBetween('install_time', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('channel, COUNT(*) as install_count, DATE(install_time) as stat_date')
            ->groupBy(['channel', 'stat_date'])
            ->get();

        // 获取渠道注册统计
        $channelRegisterStats = Db::table('gf_attribution_event')
            ->whereIn('appkey', $appIds)
            ->where('event_type', 'register')
            ->whereNotNull('channel')
            ->whereBetween('created_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
            ->selectRaw('channel, COUNT(*) as register_count, DATE(created_at) as stat_date')
            ->groupBy(['channel', 'stat_date'])
            ->get();

        // 按渠道分组数据
        $channels = [];
        $allChannels = array_unique(array_merge(
            $channelStats->pluck('channel')->toArray(),
            $channelInstallStats->pluck('channel')->toArray(),
            $channelRegisterStats->pluck('channel')->toArray()
        ));

        foreach ($allChannels as $channel) {
            $channelData = [
                'channel' => $channel,
                'clicks' => 0,
                'installs' => 0,
                'registers' => 0,
                'conversion_rate' => 0,
                'trends' => []
            ];

            // 汇总数据
            $channelData['clicks'] = $channelStats->where('channel', $channel)->sum('click_count');
            $channelData['installs'] = $channelInstallStats->where('channel', $channel)->sum('install_count');
            $channelData['registers'] = $channelRegisterStats->where('channel', $channel)->sum('register_count');
            
            if ($channelData['clicks'] > 0) {
                $channelData['conversion_rate'] = round(($channelData['installs'] / $channelData['clicks']) * 100, 2);
            }

            // 构建趋势数据
            $dateRange = $this->generateDateRange($startDate, $endDate);
            foreach ($dateRange as $date) {
                $clickCount = $channelStats->where('channel', $channel)->where('stat_date', $date)->sum('click_count');
                $installCount = $channelInstallStats->where('channel', $channel)->where('stat_date', $date)->sum('install_count');
                $registerCount = $channelRegisterStats->where('channel', $channel)->where('stat_date', $date)->sum('register_count');

                $channelData['trends'][] = [
                    'date' => $date,
                    'clicks' => $clickCount,
                    'installs' => $installCount,
                    'registers' => $registerCount,
                    'conversion_rate' => $clickCount > 0 ? round(($installCount / $clickCount) * 100, 2) : 0
                ];
            }

            $channels[] = $channelData;
        }

        // 按转化率排序
        usort($channels, function($a, $b) {
            return $b['conversion_rate'] <=> $a['conversion_rate'];
        });

        return $channels;
    }
}